﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace theguineasyndrome
{
    abstract public class LevelElement : ILevelObject
    {
        public enum Side
        {
            LEFT,
            RIGHT,
            TOP,
            BOTTOM
        }

        protected Level level;
        protected Vector2 position;
        protected Rectangle rectangle;
        protected Texture2D texture;
        private bool real; // inserted in the map

        abstract public bool isDynamic();
        abstract public void queueDrawing(Camera camera);

        private Color color;

        public LevelElement(Level level, Texture2D texture, Vector2 position)
        {
            this.level = level;
            this.texture = texture;
            this.real = false;
            this.position = position;
            rectangle = new Rectangle((int)position.X, (int)position.Y, (int)texture.Width, (int)texture.Height);
            color = Color.White;
        }

        public void setTexture(Texture2D texture)
        {
            this.texture = texture;
        }

        public void setReal()
        {
            real = true;
        }

        public void updateDynamic()
        {
            level.updateDynamic(this);
        }

        public Rectangle getRectangle()
        {
            return rectangle;
        }

        public virtual void Update(GameTime gameTime)
        {
            
        }

        public virtual void notifyCharacterOver(Character character)
        {
            
        }

        public virtual void notifyCharacterAway()
        {
            
        }

        public void setColor(Color color)
        {
            this.color = color;
        }

        public virtual void Draw(SpriteBatch spriteBatch, Camera camera)
        {
            spriteBatch.Draw(texture, camera.getDstRect(rectangle), color);
        }

        public float Left
        {
            get { return position.X; }

            set
            {
                if (real)
                {
                    Vector2 oldCenter = Center;
                    position.X = value;
                    rectangle.X = (int)position.X;
                    level.moveElement(this, oldCenter);
                }
                else
                {
                    position.X = value;
                    rectangle.X = (int)value;
                }
            }
        }

        public float Right
        {
            get { return position.X + Width; }

            set
            {
                if (real)
                {
                    Vector2 oldCenter = Center;
                    position.X = value - Width;
                    rectangle.X = (int)position.X;
                    level.moveElement(this, oldCenter);
                }
                else
                {
                    position.X = value - Width;
                    rectangle.X = (int)(value - Width);
                }
            }
        }

        public float Top
        {
            get { return position.Y; }

            set
            {
                if (real)
                {
                    Vector2 oldCenter = Center;
                    position.Y = value;
                    rectangle.Y = (int)position.Y;
                    level.moveElement(this, oldCenter);
                }
                else
                {
                    position.Y = value;
                    rectangle.Y = (int)position.Y;
                }
            }
        }

        public float Bottom
        {
            get { return position.Y + Height; }

            set
            {
                if (real)
                {
                    Vector2 oldCenter = Center;
                    position.Y = value - Height;
                    rectangle.Y = (int)position.Y;
                    level.moveElement(this, oldCenter);
                }
                else
                {
                    position.Y = value - Height;
                    rectangle.Y = (int)position.Y;
                }
            }
        }

        public virtual float Depth
        {
            get { return Bottom; }
        }

        public float Width
        {
            get { return rectangle.Width; }
        }

        public float Height
        {
            get { return rectangle.Height; }
        }

        public Vector2 Center
        {
            get { return new Vector2((Right + Left) / 2, (Bottom + Top) / 2); }

            set
            {
                if (real)
                {
                    Vector2 oldCenter = Center;
                    position.X = value.X - Width / 2;
                    position.Y = value.Y - Height / 2;
                    rectangle.X = (int)position.X;
                    rectangle.Y = (int)position.Y;
                    level.moveElement(this, oldCenter);
                }
                else
                {
                    position.X = value.X - Width / 2;
                    position.Y = value.Y - Height / 2;
                    rectangle.X = (int)position.X;
                    rectangle.Y = (int)position.Y;
                }
            }
        }

        public virtual Vector2 Position
        {
            get { return new Vector2(Left, Top); }

            set
            {
                if (real)
                {
                    Vector2 oldCenter = Center;
                    position = value;
                    rectangle.X = (int)value.X;
                    rectangle.Y = (int)value.Y;
                    level.moveElement(this, oldCenter);
                }
                else
                {
                    position = value;
                    rectangle.X = (int)value.X;
                    rectangle.Y = (int)value.Y;
                }
            }
        }

        public Side getSide(Vector2 position, Vector2 speed)
        {
            Side side;
            if (speed.X > 0) // top left bottom
            {
                if (speed.Y > 0) // top left
                {
                    float diffX = position.X - Left;
                    float diffY = position.Y - Top;

                    if (diffY < diffX)
                        side = Side.TOP;

                    else
                        side = Side.LEFT;
                }
                else // bottom left
                {
                    float diffX = position.X - Left;
                    float diffY = Bottom - position.Y;

                    if (diffY < diffX)
                        side = Side.BOTTOM;

                    else
                        side = Side.LEFT;
                }
            }
            else // top right bottom
            {
                if (speed.Y > 0) // top right
                {
                    float diffX = Right - position.X;
                    float diffY = position.Y - Top;

                    if (diffY < diffX)
                        side = Side.TOP;

                    else
                        side = Side.RIGHT;
                }
                else // bottom right
                {
                    float diffX = Right - position.X;
                    float diffY = Bottom - position.Y;

                    if (diffY < diffX)
                        side = Side.BOTTOM;

                    else
                        side = Side.RIGHT;
                }
            }
            return side;
        }

        public string getTextureName()
        {
            return texture.Name;
        }

    }
}
